package org.example.shop.shiro;

import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.Set;

@Component
@Slf4j
public class UserRealm extends AuthorizingRealm {
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UserToken;
    }

    /**
     * 用户权限的读取
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("开始进行用户授权");
        String token = principalCollection.toString();
        log.info("==>{}", token);
        // 到redis或者数据查询该token拥有的权限
        Set<String> roles = new HashSet<>(); // 角色列表
        Set<String> perms = new HashSet<>(); // 权限列表
        // 添加一个测试的权限
        perms.add("test:per:query");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);  // 设置角色
        info.setStringPermissions(perms); // 设置权限
        return info;
    }

    /**
     * 用户身份认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("开始进行身份认证");
        String token = (String) authenticationToken.getCredentials();

        if (StringUtils.isEmpty(token) || token.equals("test")) {
            throw new AuthenticationException("token不正确");
        }
        // 到redis或者数据查询token
        // 此处应该进行响应的用户信息验证 比如状态等等
        log.info("==>{}", token);

        return new SimpleAuthenticationInfo(token, token, getName());
    }
}
